#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include <signal.h>

/*
 *
连续点击三次ctrl + C ,各种场景如下：

这是不加信号阻塞的情况，每个信号任务都没有执行完，就被下一个信号打断了
^CI catch the signal 2
Task start
^CI catch the signal 2
Task end
^CI catch the signal 2
Task start
Task end
表现效果让sleep(5)失效了
 
这是在任务上下加了信号阻塞的函数，第一个信号任务没有被打断。但是并没有实现一个Ctrl + C 对应一个任务的效果
^CI catch the signal 2
Task start
^C^CTask end
I catch the signal 2

*/

typedef void (*sighandler_t)(int);

sighandler_t oldact;

void handler(int sig){
	printf("I catch the signal %d\n", sig);
}

void mytask(){
	printf("Task start\n");
	sleep(5);
	printf("Task end\n");
}

int main(){
	//初始化sigaction
	struct sigaction act;
	act.sa_handler = handler;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);

	//信号捕捉1：将CRTL + C信号的行为 由杀掉进程改成 打印
	sigaction(SIGINT, &act, NULL);
	//信号捕捉2：将SIGHUP信号的行为 由杀掉进程改称 打印
	sigaction(SIGHUP, &act, NULL);

	//将SIGINT、SIGHUP信号添加到sigset集合中，为后续实现信号阻塞作准备
	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGHUP);

	//终止主线程，等待信号的到来
	pause();

	//循环
	while(1){
		//实现对信号的阻塞,使新来的信号不会干扰任务的执行
		sigprocmask(SIG_BLOCK, &set, NULL);
		mytask();
		//执行完任务后，解除对信号的阻塞
		sigprocmask(SIG_UNBLOCK, &set, NULL);
		pause();
	}

}
